{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "eac17ab0-8e70-4acf-9482-8cc956785c72",
   "metadata": {},
   "source": [
    "# 学习function call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "60549b90-95b2-4b9c-aa3f-548a7bd78e33",
   "metadata": {},
   "outputs": [],
   "source": [
    "from zai import ZhipuAiClient\n",
    "import json"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "166172aa-4d83-4e18-b147-924c5f159722",
   "metadata": {},
   "source": [
    "## 1、定义一个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a3efcd22-e49e-4fd4-95ea-7cf0a57413de",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 计算器函数\n",
    "def my_calculator(a, b, opt):\n",
    "    if opt == \"+\":\n",
    "        return a + b\n",
    "    elif opt == \"-\":\n",
    "        return a - b\n",
    "    elif opt == \"*\":\n",
    "        return a - b\n",
    "    elif opt == \"/\":\n",
    "        return a - b\n",
    "    else:\n",
    "        return \"无法计算\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b81e044-ea43-401e-9124-4ad5bdb68ded",
   "metadata": {},
   "source": [
    "## 2、注册这个函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0794eb2-e2ee-4557-9d10-a0644af5bec6",
   "metadata": {},
   "source": [
    "不同的API注册函数的方式不一样，你得看说明文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "9178bd14-c0d5-4a83-a431-f1ab8653ec4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 他的作用是让大模型知道有哪些tool可以用，以及这些tool都有什么用\n",
    "tools = [\n",
    "    # 一个大括号里面就是一个tool函数\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"my_calculator\",\n",
    "            \"description\": \"计算两个数的加减乘除四则运算，第一个参数是a，第二个参数是b，第三个参数是opt，当其他运算传入的时候就会输出无法计算\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"a\": {\n",
    "                        \"type\": \"int\",\n",
    "                        \"description\": \"计算器的第一个操作数\"\n",
    "                    },\n",
    "                    \"b\": {\n",
    "                        \"type\": \"int\",\n",
    "                        \"description\": \"计算器的第二个操作数\"\n",
    "                    },\n",
    "                    \"opt\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"计算器的操作符\"\n",
    "                    }\n",
    "                },\n",
    "                \"required\": [\"a\", \"b\", \"opt\"]\n",
    "            }\n",
    "        }\n",
    "    }\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d30ad4b-3558-4baf-abfe-b1eb7a47db42",
   "metadata": {},
   "source": [
    "## 3、请求大模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c38ecf8f-a638-4b0a-9c2d-e0b9ff8a7782",
   "metadata": {},
   "outputs": [],
   "source": [
    "from config import api_key\n",
    "client = ZhipuAiClient(\n",
    "    base_url=\"https://open.bigmodel.cn/api/paas/v4/\",  # 你访问的在线模型的API\n",
    "    api_key=api_key\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "55bccfcf-2f94-4548-bdc8-033e0800f2c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "请输入 你好呀\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "你好！很高兴见到你！有什么我可以帮助你的吗？\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "'NoneType' object is not iterable",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[29]\u001b[39m\u001b[32m, line 18\u001b[39m\n\u001b[32m     13\u001b[39m \u001b[38;5;28mprint\u001b[39m(response.choices[\u001b[32m0\u001b[39m].message.content)\n\u001b[32m     14\u001b[39m \u001b[38;5;66;03m# print(response.choices[0].message.reasoning_content)\u001b[39;00m\n\u001b[32m     15\u001b[39m \u001b[38;5;66;03m# print(response.choices[0].message.tool_calls)  # 工具链\u001b[39;00m\n\u001b[32m     16\u001b[39m \n\u001b[32m     17\u001b[39m \u001b[38;5;66;03m# 执行函数\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m18\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m tool \u001b[38;5;129;01min\u001b[39;00m response.choices[\u001b[32m0\u001b[39m].message.tool_calls:\n\u001b[32m     19\u001b[39m     \u001b[38;5;28;01mif\u001b[39;00m tool.function.name == \u001b[33m\"\u001b[39m\u001b[33mmy_calculator\u001b[39m\u001b[33m\"\u001b[39m:\n\u001b[32m     20\u001b[39m         result = my_calculator(**json.loads(tool.function.arguments))\n",
      "\u001b[31mTypeError\u001b[39m: 'NoneType' object is not iterable"
     ]
    }
   ],
   "source": [
    "query = input(\"请输入\")\n",
    "response = client.chat.completions.create(\n",
    "    model=\"glm-4.5-flash\",\n",
    "    messages=[\n",
    "        {\"role\":\"user\", \"content\":query},   # 系统提示词\n",
    "    ],\n",
    "    # 真正的注册\n",
    "    tools=tools,\n",
    "    tool_choice=\"auto\"\n",
    ")\n",
    "\n",
    "# print(response)\n",
    "print(response.choices[0].message.content)\n",
    "# print(response.choices[0].message.reasoning_content)\n",
    "# print(response.choices[0].message.tool_calls)  # 工具链\n",
    "\n",
    "# 执行函数\n",
    "if response.choices[0].message.tool_calls：  # 当工具链不为空的时候采取调用工具\n",
    "    for tool in response.choices[0].message.tool_calls:\n",
    "        if tool.function.name == \"my_calculator\":\n",
    "            result = my_calculator(**json.loads(tool.function.arguments))\n",
    "            print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "527152b5-4c89-423a-abc7-4e9b7f27bd71",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "llm_learn",
   "language": "python",
   "name": "llm_learn"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
